﻿/// <reference path="../Libraries/jasmine/jasmine.d.ts" />
/// <reference path="../Jasmine.Matchers.ts" />

declare module jasmine {
    interface Matchers {
        toHaveModel(modelName: string): boolean;
        toHaveView(viewName: string): boolean;
        toHaveController(controllerName: string): boolean;
        toHaveStore(storeName: string): boolean;
        toHaveRef(refName: string): boolean;
        toHaveConfig(configName: string): boolean;
        toRequire(className: string): boolean;
        toExtend(className: string): boolean;
        toOverride(className: string): boolean;
        toHaveBeenCalledWithConfig(expected: any, arg?: number): boolean;
        toHaveAddedListener(expected: any): boolean;
        toHaveRemovedListener(expected: any): boolean;
    }
}

describe('ExtSpec.Jasmine.Matchers', function () {
    'use strict';

    beforeEach(function () {
        jasmine.addMatchers(ExtSpec.Jasmine.Matchers);
    });

    describe('toRequire', function () {
        it('should pass given a matching requirement', function () {
            var instance = {
                    requires: [
                        'Any.class.Name'
                    ]
                };

            expect(instance).toRequire('Any.class.Name');
        });

        it('should fail given a missing requirement', function () {
            var instance = {
                    requires: []
                };

            expect(instance).not.toRequire('Any.other.Name');
        });
    });

    describe('toHaveConfig', function () {
        it('should pass given an instance with a matching config property', function () {
            var instance = {
                    config: {
                        myProp: 22
                    }
                };

            expect(instance).toHaveConfig('myProp');
        });

        it('should fail given an instance without a matching config property', function () {
            var instance = {
                config: {
                    myOtherProp: 22
                }
            };

            expect(instance).not.toHaveConfig('myProp');
        });
    });

    describe('toHaveBeenCalledWithConfig', function () {
        var spyWithConfig,
            config = {
                firstKey: true,
                secondKey: 2,
                thirdKey: 'three',
                fourthKey: [1, 2, 3, 4]
            };

        beforeEach(function () {
            spyWithConfig = jasmine.createSpy('spyWithConfig');
        });

        it('should pass given a first argument config with two matching keys', function () {
            spyWithConfig(config);

            expect(spyWithConfig).toHaveBeenCalledWithConfig({
                firstKey: true,
                thirdKey: 'three'
            });
        });

        it('should pass given a second argument config with three matching keys', function () {
            spyWithConfig('some name', config);

            expect(spyWithConfig).toHaveBeenCalledWithConfig({
                firstKey: true,
                secondKey: 2,
                thirdKey: 'three'
            }, 1);
        });

        it('should fail given a first argument config with non matching key', function () {
            spyWithConfig(config);

            expect(spyWithConfig).not.toHaveBeenCalledWithConfig({
                fifthKey: 555.555
            });
        });
    });
});